﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DOTNET101_Nullable
{
    class Program
    {
        static void Main(string[] args)
        {
            NullableExample.Test();
        }
    }

    class NullableExample
    {
        public static void Test()
        {
            int? num = null;
            if (num.HasValue == true)
            {
                System.Console.WriteLine("num = " + num.Value);
            }
            else
            {
                System.Console.WriteLine("num = Null");
            }

            //y is set to zero
            int y = num.GetValueOrDefault();

            // num.Value throws an InvalidOperationException if num.HasValue is false
            try
            {
                y = num.Value;
            }
            catch (System.InvalidOperationException e)
            {
                System.Console.WriteLine(e.Message);
            }

            int? num1 = 10;
            int? num2 = null;
            if (num1 >= num2)
            {
                System.Console.WriteLine("num1 is greater than or equal to num1");
            }
            else
            {
                // num1 is NOT less than num2
            }

            int? c = null;

            // d = c, unless c is null, in which case d = -1.
            int d = c ?? -1;


            int? ef = null;
            int? ff = null;

            // g = e or f, unless e and f are both null, in which case g = -1.
            int gf = ef ?? ff ?? -1;


            int? a = 10;
            int? b = null;

            a++;         // Increment by 1, now a is 11.
            a = a * 10;  // Multiply by 10, now a is 110.
            a = a + b;   // Add b, now a is null.

            bool? bc = null;
            object o = bc;
            // Now o is null.

            bool? bd = false;
            int? i = 44;
            object bBoxed = bd; // bBoxed contains a boxed bool.
            object iBoxed = i; // iBoxed contains a boxed int.

            bool? b2 = (bool?)bBoxed;
            int? i2 = (int?)iBoxed;


            bool? bx = null;
            object boxedB = b;
            if (bx == null)
            {
                // True.
            }
            if (boxedB == null)
            {
                // Also true.
            }


            double? dx = 44.4;
            object iBoxedx = d;
            // Access IConvertible interface implemented by double.
            IConvertible ic = (IConvertible)iBoxedx;
            int ix = ic.ToInt32(null);
            string str = ic.ToString();

            System.Type type = typeof(int?);

            int? ib = 5;
            Type t = ib.GetType();
            Console.WriteLine(t.FullName); //"System.Int32"
        }
    }

}
